本來想直接談Sentry和網頁效能的話題,但突然想到,我們在查看網頁效能的時候、是想看在「每一個頁面」的狀態,也就是說Sentry要能正確的追蹤到該頁面的url、以及其網頁表現。但前幾篇忽略這一點了,所以這一篇來補上。
在React+React-router的專案中,要讓Sentry能夠正確追蹤到React Router的相關資訊,需要根據使用的react-router
版本來選擇嵌入方法。今天我們直接用最新版本(v6)來處理:
React-Router v6的配合寫法
import {
Routes,
useLocation,
useNavigationType,
createRoutesFromChildren,
matchRoutes,
} from 'react-router-dom';
Sentry.init({
dsn: SENTRY_ENDPOINT,
integrations: [
// for react router
Sentry.reactRouterV6BrowserTracingIntegration({
useEffect: useEffect,
useLocation,
useNavigationType,
createRoutesFromChildren,
matchRoutes,
}),
...
]})
目的是要讓 Sentry 實例能夠使用相對應的router hook(畢竟每個版本的react-router hook會有點不一樣),所以用宣告的方式來接入。
接著要初始化SentryRoutes
,把Routes
包進去:
const SentryRoutes = Sentry.withSentryReactRouterV6Routing(Routes);
然後就可以寫入已經定義好的page:
function App() {
return (
<BrowserRouter>
<SentryRoutes>
<Route path="/" element={<Layout />}>
<Route index element={<div>Home</div>} />
<Route path="page01" element={<Page01 />} />
<Route path="page02" element={<Page02 />} />
<Route path="page03" element={<Page03 />} />
</Route>
</SentryRoutes>
</BrowserRouter>
);
}
現在,就可以在Sentry上看到每個頁面的記錄:
那麼,如果要自己寫一個類似追蹤react-router的專案,該如何寫?
思考一下,雖然我們可以直接用window.location.pathname
來獲取當下的uri,但是如果要監聽每個路由組件的掛載與卸載,不能單純用useEffect
來監聽 window.location.pathname
(因為全局屬性不是React的state);而且不可能對每一個路由組件做侵入式的修改,全部都寫一個:
useEffect(()=>{
//監聽邏輯
},[])
也許是可以統一寫在Layout
組件中,但也是一個侵入式的寫法
而Sentry是如何做到的?就是利用react-router-dom
的api---useLocation
,然後再把<Routes/>
包起來,再利用useEffect
來監聽 location
我們來嘗試實現看看
self-sentry.js
:import { useLocation } from 'react-router-dom';
export class SelfSentry {
static withSentryReactRouter(RoutesComponent) {
return ({ children }) => {
const location = useLocation();
useEffect(() => {
console.log('--window.location.href', window.location.href);
console.log('---locaton:', location);
}, [location]);
return <RoutesComponent>{children}</RoutesComponent>;
};
}
}
<Routes>
,因為useLocation
這個hook必須是在<Router>
的子組件或後繼組件才能呼叫:const SelfSentryRoutes = SelfSentry.withSentryReactRouter(Routes);
function App() {
return (
<BrowserRouter>
<SelfSentryRoutes>
<Route path="/" element={<Layout />}>
<Route index element={<div>Home</div>} />
<Route path="page01" element={<Page01 />} />
<Route path="page02" element={<Page02 />} />
<Route path="page03" element={<Page03 />} />
</Route>
</SelfSentryRoutes>
</BrowserRouter>
);
}
這時就可以看到,在路由切換的時候,我們的SelfSentry sdk是可以獲取到當下的 uri:
在這篇文章中,我們探討了如何將 Sentry 與 React Router v6 結合,以正確追蹤頁面效能。透過使用 Sentry 提供的 reactRouterV6BrowserTracingIntegration
,我們能夠輕鬆整合 React Router 的相關資料,並使用相應的 hooks 來追蹤頁面路由變化。接著,我們手寫了一個簡單的自定義追蹤工具,展示了如何利用 useLocation
和 useEffect
來實現類似 Sentry 的頁面追蹤功能。這讓我們更加理解 Sentry 如何利用 React Router 的 API 來追蹤頁面效能和路由資訊。
不會前端的我問一下 TPM 在這裡的具體用處?
是指一分鐘能刷新幾次 還是@@? 我是真不懂,請教
我連它全名都不知道 XD (Transaction per Minite?)
看那個很像是某一頁的指標,但不會有終端使用者一分鐘狂刷新該頁面吧(除了搶票 XD)
還是這對 Server side render 比較有用?
後面的 p50~p95, users 都能理解,前者是使用者體驗相關的效能指標,一個就該頁的點擊過得使用者數量? 但TPM我自己不知道怎理解它
對Transaction per Minute---每分鐘的transition次數~
不過在Sentry sdk中,前端(spa)應該只default記錄到pageload和navigation(單元測試中只看到這兩個)
在前端來說,如果有高於平均的刷新和導航,可能會是什麼資源加載有誤、頁面顯示異常、或者就是頁面loading變慢,所以使用者一直刷新或者跳入跳出